# -*- coding: utf-8 -*-
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.parsers import JSONParser
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import detail_route, list_route
from django.db.models import *
from django.contrib.auth.models import User
import os
import os.path
import shutil
from django.core.files.base import ContentFile,File
from PIL import Image
import cv2

from models import*
from serializer import*
from AIAlbum.settings import *

from AIAlbum.classifier import *
from AIAlbum.imghandler import *
from AIAlbum.SearchSimilar import *
from AIAlbum.evaluation import *
from AIAlbum.stylecmd import *
from AIAlbum.FaceDetection import *
from AIAlbum.FaceJudge import *
from AIAlbum.FaceTool import *
from AIAlbum.JudgeSmile import *
from AIAlbum.preproccessor import *
# Create your views here.

class ImgInfoViewSet(viewsets.ModelViewSet):
    serializer_class = ImgInfoSerializer

    def get_queryset(self):
        if not 'search' in self.request.GET:
            ft = ImgInfo.objects.all()
        else:
            ft = ImgInfo.objects.filter(ImgID__contains=self.request.GET['search'])
        return ft

    def create(self, request):
        serialized=ImgInfoSerializer(data=request.data)
        print 'DIR::::::',dir(request.data['UpImage'])
        print 'NAME:::::',str(request.data['UpImage'].name)
        ImgAddress=str(MEDIA_ROOT).replace('\\','/')+'/pic/'+str(request.data['UpImage'].name)
        if serialized.is_valid():
            #Update the ImgID
            serialized.validated_data['ImgID']=str(get_time_stamp())
            #Update the UploadDate
            serialized.validated_data['UploadDate']=str(Current_Date())
            #Update the StorePath
            serialized.validated_data['StorePath']=ImgAddress
            #Init the TakenDate
            serialized.validated_data['TakenDate']=str(Current_Date())
            # serialized.validated_data['TakenDate']=str(getDate(ImgAddress))
            #Init the Imghs
            serialized.validated_data['Imghs']='FF'
            # serialized.validated_data['Imghs']=get_file_hash(ImgAddress)
            #Init the Category
            serialized.validated_data['RawCategory']='-1'
            serialized.validated_data['NewCategory']='-1'
            serialized.save()
            return Response(serialized.data)
        else:
            return Response(serialized.errors)

    def update(self, request,pk=None):
        ob=self.get_object() #Group.objects.get(pk = pk)
        serialized=ImgInfoSerializer(ob,data=request.data)
        if serialized.is_valid():
            serialized.save()
            serialized = self.serializer_class(ob)
            return Response(serialized.data)
        else:
            return Response(serialized.errors)

    @list_route()#更新对象字段
    def update_fields(self, request):
        imgs=ImgInfo.objects.filter(Imghs__exact='FF')
        nt,tf=New_Net()#Build a caffe net
        pics=ImgInfo.objects.all()
        hash_list=[]
        for pic in pics:
            hash_list.append(pic.Imghs)
        for mg in imgs:
            mg.StorePath=str(MEDIA_ROOT).replace('\\','/')+'/'+str(mg.UpImage.name)
            ImgAddress=mg.StorePath
            mg.TakenDate=str(getDate(ImgAddress))
            tmp=get_file_hash(ImgAddress)
            if tmp in hash_list:
                mg.delete()
                TmpAddress=mg.UpImage.path
                if os.path.exists(TmpAddress):
                    try:
                        os.remove(TmpAddress)
                    except:
                        return Response({'code':'21','message':'Miss Problem when deleting file','data':''})
                else:
                    return Response({'code':'20','message':'No avalible path or filename','data':''})
                return Response({'code':'01','message':'Exists the same photos','data':''})
            mg.Imghs=get_file_hash(ImgAddress)
            ic=classify(nt,tf,ImgAddress)
            icc=decide(ic)
            mg.RawCategory=str(icc)
            mg.NewCategory=str(icc)
            mg.save()
            print ImgAddress,' finished!'
        return Response({'code':'0','message':'','data':''})

    @list_route()
    def Select_all(self, request):#查询已更新或未更新或所有对象
        if 'selected' in self.request.GET:
            if self.request.GET['selected'] == '0':#still not update
                imgs=ImgInfo.objects.filter(Imghs__exact='FF').order_by('TakenDate','UploadDate','ImgID')
            elif self.request.GET['selected'] == '1':#finished update
                imgs=ImgInfo.objects.exclude(Imghs='FF')
            else:#select all
                imgs=ImgInfo.objects.all()
            if imgs.count()==0:
                return Response({'code':'5','message':'SELECT NULL','data':''})
            else:
                serializer=ImgInfoSerializer(imgs, many=True)
                return Response({'code':'0','message':'','data':serializer.data})
        else:
            imgs=ImgInfo.objects.all()
            if imgs.count()==0:
                return Response({'code':'5','message':'SELECT NULL','data':''})
            else:
                serializer=ImgInfoSerializer(imgs, many=True)
                return Response({'code':'0','message':'','data':serializer.data})
            # serializer=ImgInfoSerializer(imgs, many=True)

    @list_route()
    def statistical(self, request):#统计未更新对象的个数
        imgs=ImgInfo.objects.filter(Imghs__exact='FF')
        cnt=imgs.count()
        ans=str(cnt)
        return Response({'code':'0','message':'','data':ans})

    @detail_route(methods=['get'],url_path='partset')
    def part_set(self, request, pk=None):#修改部分字段,如分类和描述等
        image=self.get_object()
        if 'category' in self.request.GET:
            image.NewCategory=self.request.GET['category']
            image.save()
            return Response({'code':'0','message': 'Successfully Changed newcategory!','data':''})
        if 'txt' in self.request.GET:
            image.Description=self.request.GET['txt']
            image.save()
            return Response({'code':'0','message': 'Successfully Changed Description!','data':''})
        return Response({'code':'4','message': 'Unknown Action!','data':''})

    @list_route()
    def Select_Hash(self, request):
        imgs=ImgInfo.objects.all()
        hash_list=[]
        for im in imgs:
            hash_list.append(im.Imghs)
        return Response({'code':'0','message':'','data':hash_list})

    @list_route()
    def Select_Fields(self, request):
        if 'date' in self.request.GET:
            dt=self.request.GET['date']
            ft = ImgInfo.objects.filter(TakenDate__contains=dt).order_by('TakenDate','UploadDate','ImgID')
            serializer=ImgInfoSerializer(ft, many=True)
            if ft.count()==0:
                return Response({'code':'5','message':'SELECT NULL','data':''})
            else:
                return Response({'code':'0','message':'','data':serializer.data})
        if 'hash' in self.request.GET:
            hs=self.request.GET['hash']
            ft = ImgInfo.objects.filter(Imghs__contains=hs).order_by('TakenDate','UploadDate','ImgID')
            serializer=ImgInfoSerializer(ft, many=True)
            if ft.count()==0:
                return Response({'code':'5','message':'SELECT NULL','data':''})
            else:
                return Response({'code':'0','message':'','data':serializer.data})
        if 'hashes' in self.request.GET:
            hslist=self.request.GET['hashes'].split(',')
            ft = ImgInfo.objects.filter(Imghs__in=hslist).order_by('TakenDate','UploadDate','ImgID')
            serializer=ImgInfoSerializer(ft, many=True)
            if ft.count()==0:
                return Response({'code':'5','message':'SELECT NULL','data':''})
            else:
                return Response({'code':'0','message':'','data':serializer.data})
        if 'Category' in self.request.GET:
            cty=self.request.GET['Category']
            ft = ImgInfo.objects.filter(NewCategory__contains=cty).order_by('TakenDate','UploadDate','ImgID')
            serializer=ImgInfoSerializer(ft, many=True)
            if ft.count()==0:
                return Response({'code':'5','message':'SELECT NULL','data':''})
            else:
                return Response({'code':'0','message':'','data':serializer.data})
        return Response({'code':'5','message':'Unknown Action','data':''})

    @list_route()
    def timeline(self, request):
        if ('date' in self.request.GET) and ('count' in self.request.GET):
            cnt=int(self.request.GET['count'])
            dstr=str(self.request.GET['date'])
            nd=count_date(dstr,cnt)
            if is_valid_date(dstr) ==False:
                return Response({'code':'3','message':'No Date Type!','data':''})
            if cnt < 0:
                ft = ImgInfo.objects.filter(TakenDate__range=(nd,dstr)).order_by('TakenDate','UploadDate','ImgID')
            elif cnt > 0:
                ft = ImgInfo.objects.filter(TakenDate__range=(dstr,nd)).order_by('TakenDate','UploadDate','ImgID')
            else:
                ft = ImgInfo.objects.filter(TakenDate__contains=dstr).order_by('TakenDate','UploadDate','ImgID')
        elif 'date' in self.request.GET:
            ft = ImgInfo.objects.filter(TakenDate__contains=dstr).order_by('TakenDate','UploadDate','ImgID')
        else:
            return Response({'code':'3','message':'No Date Type!','data':''})
        serializer=ImgInfoSerializer(ft, many=True)
        return Response({'code':'0','message':'','data':serializer.data})

    @list_route()
    def Find_Similar(self, request):
        imgs=ImgInfo.objects.all()
        cnt=imgs.count()
        imgscontent=[]
        for m in imgs:
            print m.StorePath,' is ok!'
            mc=cv2.imread(m.StorePath)
            imgscontent.append(mc)
        outerlist=range(cnt)
        innerlist=range(cnt)
        ans=[]
        for i in outerlist:
            p1=imgscontent[i]
            innerlist.remove(i)
            subans=[]
            if len(innerlist)==0:
                break
            subans.append(imgs[i].id)
            for j in innerlist:
                if imgs[i].NewCategory != imgs[j].NewCategory:
                    continue
                p2=imgscontent[j]
                degree = classify_pHash(p1,p2)
                # print imgs[i].StorePath,'  ',imgs[j].StorePath,'   ',degree
                if degree < 8:
                    # if imgs[i].NewCategory != imgs[j].NewCategory:
                    #     continue
                    subans.append(imgs[j].id)
                    innerlist.remove(j)
                    outerlist.remove(j)
                    print imgs[i].StorePath,'  ',imgs[j].StorePath,'   ',degree,'  ',imgs[i].NewCategory,'   ',imgs[j].NewCategory
                if len(innerlist)==0:
                    break
            if len(subans) > 1:
                ft = ImgInfo.objects.filter(id__in=subans).order_by('TakenDate','UploadDate','ImgID')
                serializer=ImgInfoSerializer(ft, many=True)
                ans.append(serializer.data)
        if len(ans)==0:
            return Response({'code':'3','message':'QuerySet is null!','data':''})
        else:
            return Response({'code':'0','message':'','data':ans})

    @list_route()
    def GetHighScoreImgs(self, request):
        imgs=ImgInfo.objects.all()
        nt,ft=aesthetics_net()
        ans=[]
        cnt=0
        for img in imgs:
            imgpath=img.StorePath
            r=aesthetics_evaluate(nt,ft,imgpath)
            print img.StorePath,':::: is ok!'
            if r==1:
                ans.append(cnt)
            cnt=cnt+1
        if len(ans)>0:
            ft = ImgInfo.objects.filter(id__in=ans).order_by('TakenDate','UploadDate','ImgID')
            serializer=ImgInfoSerializer(ft, many=True)
            # r=
            return Response({'code':'0','message':'','data':serializer.data})
        else:
            return Response({'code':'3','message':'QuerySet is null!','data':''})

    @list_route()
    def DeleteImgs(self, request):
        if 'id' in self.request.GET:
            dt=self.request.GET['id']
            ft = ImgInfo.objects.filter(id__exact=dt)
            fp=ft[0].StorePath
            if os.path.exists(fp):
                os.remove(fp)
                print fp,' removed!'
            else:
                return Response({'code':'2','message':'Unknown PATH','data':''})
            ImgInfo.objects.filter(id__exact=dt).delete()
            return Response({'code':'0','message':'','data':fp})
        # else:
        #     return Response({'code':'2','message':'Unknown Actions','data':''})
        elif 'ids' in self.request.GET:
            IDlist=self.request.GET['ids'].split(',')
            fts = ImgInfo.objects.filter(id__in=IDlist).order_by('id')
            pl=[]
            for ft in fts:
                fp=ft.StorePath
                ip=ft.id
                if os.path.exists(fp):
                    os.remove(fp)
                    ImgInfo.objects.filter(id__exact=ip).delete()
                    pl.append(fp)
                    print fp,' removed!'
                else:
                    return Response({'code':'2','message':'Unknown PATH','data':''})
            return Response({'code':'0','message':'','data':pl})
        else:
            return Response({'code':'2','message':'Unknown Actions','data':''})

    @list_route()
    def TimeAxis(self, request):
        imgs=ImgInfo.objects.all().order_by('TakenDate','UploadDate','ImgID')
        dateList=[]
        ans=[]
        subans=[]
        for img in imgs:
            if img.TakenDate in dateList:
                subans.append(img.id)
            elif len(dateList)>0:
                ft=ImgInfo.objects.filter(id__in=subans).order_by('id')
                serializer=ImgInfoSerializer(ft, many=True)
                ans.append(serializer.data)
                subans=[]
                dateList.append(img.TakenDate)
                subans.append(img.id)
            elif len(dateList)==0:
                dateList.append(img.TakenDate)
                subans.append(img.id)
        if len(subans)>0:
            ft=ImgInfo.objects.filter(id__in=subans).order_by('id')
            serializer=ImgInfoSerializer(ft, many=True)
            ans.append(serializer.data)
            subans=[]
        if len(ans)==0:
            return Response({'code':'5','message':'QuerySet is Null','data':''})
        else:
            return Response({'code':'0','message':'','data':ans})

    @detail_route(methods=['get'],url_path='transferstyle')
    def transfer_style(self, request, pk=None):
        image=self.get_object()
        if 'style' in self.request.GET:
            smno=self.request.GET['style']
            if smno == '1':
                styleimg=str(BASE_DIR).replace('\\','/')+'/mysrc/StyleTransfer/images/style/starry_night.jpg'
                # BASE_DIR
                # styleimg='F:/style-transfer/style-transfer-master/images/style/starry_night.jpg'
            elif smno == '2':
                styleimg=str(BASE_DIR).replace('\\','/')+'/mysrc/StyleTransfer/images/style/dreamland.jpg'
            elif smno == '3':
                styleimg=str(BASE_DIR).replace('\\','/')+'/mysrc/StyleTransfer/images/style/yell.jpg'
            elif smno == '4':
                styleimg=str(BASE_DIR).replace('\\','/')+'/mysrc/StyleTransfer/images/style/forest.jpg'
            elif smno == '5':
                styleimg=str(BASE_DIR).replace('\\','/')+'/mysrc/StyleTransfer/images/style/lake.jpg'
            else:
                return Response({'code':'6','message':'Sorry,unknown style','data':''})
            style_path=str(BASE_DIR).replace('\\','/')+'/upload/style'
            rt=mkdir(style_path)
            contentimg = image.StorePath
            modelname = 'googlenet'
            pyscript = str(BASE_DIR).replace('\\','/')+'/mysrc/StyleTransfer/style.py'
            # pyscript = str(BASE_DIR).replace('\\','/')+'/AIAlbum/style.py'
            execute_style_transfer(pyscript,styleimg,contentimg,modelname,-1)
            PreOut=str(BASE_DIR).replace('\\','/')+'/mysrc/StyleTransfer/outputs/'
            PreFix='/upload/style/'
            PostFix='-googlenet-content-1e4-512.jpg'
            CName=os.path.splitext(os.path.split(contentimg)[1])[0]
            SName=os.path.splitext(os.path.split(styleimg)[1])[0]
            TotalPath=PreFix+str(CName)+'-'+str(SName)+PostFix
            ABSShow=str(BASE_DIR).replace('\\','/')+TotalPath
            ABSOut=PreOut+str(CName)+'-'+str(SName)+PostFix
            print 'ABSOut::::',ABSOut
            print 'ABSShow::::',ABSShow
            print 'TotalPath:::',TotalPath
            # print 'Begin Copy'
            # shutil.copy(ABSOut,ABSShow)
            # print 'End Copy'
            return Response({'code':'0','message':'transfer finished','data':TotalPath})
        else:
            return Response({'code':'6','message':'Sorry,unknown style','data':''})

    @list_route()
    def SearchFace(self, request):
        if 'id' in self.request.GET:
            tmp_path=str(BASE_DIR).replace('\\','/')+'/upload/tmp'
            rt=mkdir(tmp_path)
            OldSearchList=ImgInfo.objects.all()
            # imgg=self.request.GET['id']
            myid=self.request.GET['id']
            imggs=ImgInfo.objects.filter(id__exact=myid)
            imgg=imggs[0]
            caffe_root = 'C:/Program Files/caffe/caffe-master/caffe-master'
            root=str(BASE_DIR).replace('\\','/')+'/mysrc/'
            model_def=root+'face-recognition/vgg_face_caffe/VGG_FACE_deploy.prototxt'
            model_weights=root+'face-recognition/vgg_face_caffe/VGG_FACE.caffemodel'
            #################################
            target_jpg=imgg.StorePath
            save_dir=str(MEDIA_ROOT).replace('\\','/')+'/tmp/'
            r=DetectFaces(target_jpg)
            n=len(r)
            if n==0:
                return Response({'code':'5','message':'No face datected','data':''})
            else:
                tsd=save_dir+'targetimgs/'
                if os.path.exists(tsd):
                    shutil.rmtree(tsd)
                SaveFaces(target_jpg,r,tsd)
                TargetList=filt_img(tsd)
            ans=[]
            tf,nt=Build_Face_Net(caffe_root,model_def,model_weights)
            for img_path in TargetList:
                print 'check::::',img_path
                TargetFeatures=FaceRecognice(tf,nt,img_path)
                for lookup in OldSearchList:
                    print lookup.StorePath,'  BEGIN'
                    r=DetectFaces(lookup.StorePath)
                    if len(r)==0:
                        print lookup.StorePath,' don\'t has any face'
                        continue
                    else:
                        ssd=tsd=save_dir+'searchimgs/'
                        SaveFaces(lookup.StorePath,r,ssd)
                        SearchList=filt_img(ssd)
                    for test_path in SearchList:
                        SearchFeatures=FaceRecognice(tf,nt,test_path)
                        cnt=0
                        for i in SearchFeatures:
                            if (i in TargetFeatures):
                                cnt=cnt+1
                        if cnt>2:
                            ans.append(lookup.id)
                            print lookup.StorePath,'  END'
                            shutil.rmtree(ssd)
                            print lookup.StorePath,'   ',cnt
                            break
                    try:
                        shutil.rmtree(ssd)
                    except:
                        pass
                    print lookup.StorePath,'  END'
            ft=ImgInfo.objects.filter(id__in=ans).order_by('id')
            serializer=ImgInfoSerializer(ft, many=True)
            try:
                shutil.rmtree(tsd)
            except:
                pass
            return Response({'code':'0','message':'','data':serializer.data})
        else:
            return Response({'code':'5','message':'Unknown Action...','data':''})

    @list_route()
    def Judge_Age_Gender(self, request):
        if 'id' in self.request.GET:
            tmp_path=str(BASE_DIR).replace('\\','/')+'/upload/tmp'
            rt=mkdir(tmp_path)
            myid=self.request.GET['id']
            imggs=ImgInfo.objects.filter(id__exact=myid)
            imgg=imggs[0]
            ########################
            print 'Faces Detect Begin...'
            img_path=imgg.StorePath
            faces=DetectFaces(img_path)
            if len(faces)==0:
                return Response({'code':'6','message':'No Faces','data':''})
            elif len(faces) > 1:
                return Response({'code':'6','message':'Too Many Faces','data':''})
            save_dir=str(MEDIA_ROOT).replace('\\','/')+'/tmp/Age_Gender_Faces/'
            if os.path.exists(save_dir):
                shutil.rmtree(save_dir)
            SaveFaces(img_path,faces,save_dir)
            TargetList=filt_img(save_dir)
            img_path=TargetList[0]
            print 'Faces Detect End...'
            ##########################################
            caffe_root = 'C:/Program Files/caffe/caffe-master/caffe-master'
            root=str(BASE_DIR).replace('\\','/')+'/mysrc/'
            config_root=root+'face-recognition/age_gender/'
            model_def = config_root+'deploy_gender.prototxt'
            model_weights = config_root+'gender_net.caffemodel'
            mean_filename = config_root+'mean.npy'
            tf,nt=pre_face(caffe_root,model_def,model_weights,mean_filename)
            r1=Gender_batch(tf,nt,img_path)
            model_def = config_root+'deploy_age.prototxt'
            model_weights = config_root+'age_net.caffemodel'
            tf,nt=pre_face(caffe_root,model_def,model_weights,mean_filename)
            r=Age_batch(tf,nt,img_path)
            ans=[r1,r]
            return Response({'code':'0','message':'','data':ans})
        else:
            return Response({'code':'5','message':'Unknown Action...','data':''})

    @list_route()
    def Select_Smile(self, request):
        tmp_path=str(BASE_DIR).replace('\\','/')+'/upload/tmp'
        rt=mkdir(tmp_path)
        imgs=ImgInfo.objects.all()
        is_null=1
        ans=[]
        caffe_root = 'C:/Program Files/caffe/caffe-master/caffe-master'
        root=str(BASE_DIR).replace('\\','/')+'/mysrc/face-recognition/'
        model_def=root+'FaceSmile/deploy_smile.prototxt'
        model_weights=root+'FaceSmile/face_smile.model'
        print 'Load Net!'
        tf,nt=Smile_Net(caffe_root,model_def,model_weights)
        for img in imgs:
            print img.StorePath,' begin detecting'
            faces=DetectFaces(img.StorePath)
            if len(faces)==0:
                print img.StorePath,'No faces'
                continue
            save_dir=str(MEDIA_ROOT).replace('\\','/')+'/tmp/Smile/'
            if os.path.exists(save_dir):
                shutil.rmtree(save_dir)
            SaveFaces(img.StorePath,faces,save_dir)
            TargetList=filt_img(save_dir)
            print img.StorePath,' end detecting'
            # ans=[]
            for img_path in TargetList:
                r=Is_Smile(tf,nt,img_path)
                labels = ['smooth','smile']
                print labels[r]
                if r==1:
                    ans.append(img.id)
                    is_null=0
                    break
        print ans
        if is_null==1:
            print "NULL"
        else:
            print "NOT NULL"
        ft=ImgInfo.objects.filter(id__in=ans).order_by('id')
        serializer=ImgInfoSerializer(ft, many=True)
        return Response({'code':'0','message':'','data':serializer.data})